﻿using System;
using System.Configuration;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Linq;
using CH.FourBoards.LagerWalti.Persistence.Entities;
using CH.FourBoards.LagerWalti.Persistence.Mapping;

namespace CH.FourBoards.LagerWalti.Persistence
{
    internal class DataContext : DbContext
    {

        internal DataContext()
            : base("Name=Database")
		{

			var setting = ConfigurationManager.AppSettings["Database.ForceRecreate"];
			var forceRecreate = setting != null && bool.Parse(setting);
			SetInitializer(forceRecreate);
		}

        internal DataContext(bool forceRecreate)
            : base("Name=Database")
		{
			SetInitializer(forceRecreate);
		}

		private void SetInitializer(bool forceRecreate)
		{
			if (forceRecreate) {
                Database.SetInitializer(new DropCreateDatabaseAlways<DataContext>());
			} else {
                Database.SetInitializer(new CreateDatabaseIfNotExists<DataContext>());
                Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DataContext>());
			}
		}
        
        #region Meta Data

        public DbSet<DataMigration> DataMigration { get; set; }

        #endregion

        #region Master Data

        public DbSet<TransactionType> TransactionTypes { get; set; }

        #endregion

        #region Live Data

        public DbSet<Product> Products { get; set; }
        public DbSet<Category> Categories { get; set; }
        public DbSet<Transaction> Transactions { get; set; }

        #endregion

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // Meta Data
            modelBuilder.Configurations.Add(new DataMigrationMap());

            // Master Data
            modelBuilder.Configurations.Add(new TransactionTypeMap());

            // Live Data
            modelBuilder.Configurations.Add(new ProductMap());
            modelBuilder.Configurations.Add(new CategoryMap());
            modelBuilder.Configurations.Add(new TransactionMap());
        }

        public override int SaveChanges()
        {
            try {
                return base.SaveChanges();
            } catch (DbEntityValidationException ex) {
                var message = "Entity Validation Error:\n\n";
                foreach (var error in ex.EntityValidationErrors) {
                    var entry = string.Format("The Entity [{0}] has the following errors:\n", error.Entry.Entity);
                    message += error.ValidationErrors.Aggregate(entry, (current, ve) => current + string.Format("\n - {0}: {1}", ve.PropertyName, ve.ErrorMessage));
                }
                throw new InvalidOperationException(message);
            }
        }
    }
}

